#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<strings.h>
#include<ctype.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<errno.h>
#include<sys/wait.h>
#include<errno.h>
#include <time.h>

#define SERV_PORT 13321

int std_err(const char* name)
{
    perror(name);
    exit(1);
}

int main(void)
{
    int sfd, cfd, ret;
    int len;
    pid_t pid;
    socklen_t clie_len;

    char buf[BUFSIZ], clibuf[32];

    //创建服务器套节字
    sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd == -1)
        std_err("socket");

    //定义地址类型
    struct sockaddr_in serv_addr, clie_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERV_PORT);
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    //绑定服务器的IP、端口；
    ret = bind(sfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    if(ret == -1)
        std_err("bind");

    //监听链接服务器的客户数量
    ret = listen(sfd, 3);
    if(ret == -1)
        std_err("listen");
    clie_len = sizeof(clie_addr);

    time_t t = time(0); 
    char tmp[64]; 
    strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A\n\t", localtime(&t) ); 

    while(1)
    {
        //阻塞等待客户端发起链接请求
        cfd = accept(sfd, (struct sockaddr*)&clie_addr, &clie_len);
	printf("服务器实现者20155321\t");
	printf("客户端IP：%s\n",inet_ntoa(clie_addr.sin_addr));	
	
       /* time_t t = time(0); 
        char tmp[64]; 
        strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A\n\t", localtime(&t) ); 
*/

	//这里无需打印当前时间，应该是客户端打印当前时间

        if(cfd == -1)
            std_err("accept");

        pid = fork();

        if(pid < 0)
            std_err("fork:");

        else if(pid == 0)
        {
            close(sfd);
            break;
        }
        else        //住进程实现逻辑；1.回收子进程，2，关闭不必要的文件描述父 3,继续等待客户端链接，如果有，则继续创建子进程
        {
            send(cfd,tmp,strlen(tmp),0);
    	    close(cfd);
        }
    }
    return 0;
}
